﻿Imports System.Math

Public Class dispersion
    Inherits centralTendency
    Public Function StdDev(ByVal input() As Double) As Double
        Dim average As Double = mean(input)
        Dim sum As Double = 0
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + (input(i) - average) ^ 2
        Next
        Return sqrt(sum / input.GetLength(0))
    End Function

    Public Function Variance(ByVal input() As Double) As Double
        Return (StdDev(input)) ^ 2
    End Function

    Public Function range(ByVal input() As Double) As Double
        Return (input.Max - input.Min)
    End Function

    Public Function InterQuartileRange(ByVal input() As Double) As Double
        Array.Sort(input)
        Dim length As Integer = input.GetLength(0)
        Dim array_1() As Double
        Dim array_2() As Double
        If length Mod 2 = 0 Then
            ReDim array_1((length / 2) - 1)
            ReDim array_2((length / 2) - 1)
            For i As Integer = 0 To (length / 2) - 1
                array_1(i) = input(i)
                array_2(i) = input(i + (length / 2))
            Next
        End If
        If length Mod 2 = 1 Then
            ReDim array_1(((length + 1) / 2) - 2)
            ReDim array_2(((length + 1) / 2) - 2)
            For i As Integer = 0 To ((length + 1) / 2) - 2
                array_1(i) = input(i)
                array_2(i) = input(i + ((length + 1) / 2))
            Next
        End If
        Dim medLow As Double = median(array_1)
        Dim medHi As Double = median(array_2)
        Return (medHi - medLow)
    End Function

    Public Function AbsDeviation(ByVal input() As Double) As Double
        Dim average As Double = input.Average
        Dim sum As Double
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + Abs(average - input(i))
        Next
        Return sum
    End Function

    Public Function MeanAbsDeviation(ByVal input() As Double) As Double
        Dim average As Double = input.Average()
        Dim sum As Double
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + Abs(average - input(i))
        Next
        Return (sum / input.GetLength(0))
    End Function

    Public Function MedianAbsDeviation(ByVal input() As Double) As Double
        Dim med As Double = median(input)
        Dim sum As Double
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + Abs(med - input(i))
        Next
        Return (sum / input.GetLength(0))
    End Function

    Public Function ModeAbsDeviation(ByVal input() As Double) As Double
        Dim calMode As Double = mode(input)
        Dim sum As Double
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + Abs(calMode - input(i))
        Next
        Return (sum / input.GetLength(0))
    End Function

    Public Function MeanDifference(ByVal input() As Double) As Double
        Dim sum As Double = 0
        For i As Integer = 0 To input.GetLength(0) - 1
            For j As Integer = 0 To input.GetLength(0) - 1
                sum = sum + Abs(input(i) - input(j))
            Next
        Next
        Return (sum / ((input.GetLength(0)) * (input.GetLength(0) - 1)))
    End Function

    Public Function RelativeMeanDifference(ByVal input() As Double) As Double
        Return MeanDifference(input) / input.Average
    End Function

    Public Function GiniCoeff(ByVal input() As Double) As Double
        Return RelativeMeanDifference(input) / 2
    End Function

    Public Function CoeffOfVariation(ByVal input() As Double) As Double
        Return StdDev(input) / input.Average
    End Function

    Public Function Signal2NoiseRatio(ByVal input() As Double) As Double
        Return 1 / CoeffOfVariation(input)
    End Function

    Public Function QuartileCoeff(ByVal input() As Double) As Double
        Array.Sort(input)
        Dim length As Integer = input.GetLength(0)
        Dim array_1() As Double
        Dim array_2() As Double
        If length Mod 2 = 0 Then
            ReDim array_1((length / 2) - 1)
            ReDim array_2((length / 2) - 1)
            For i As Integer = 0 To (length / 2) - 1
                array_1(i) = input(i)
                array_2(i) = input(i + (length / 2))
            Next
        End If
        If length Mod 2 = 1 Then
            ReDim array_1(((length + 1) / 2) - 2)
            ReDim array_2(((length + 1) / 2) - 2)
            For i As Integer = 0 To ((length + 1) / 2) - 2
                array_1(i) = input(i)
                array_2(i) = input(i + ((length + 1) / 2))
            Next
        End If
        Dim medLow As Double = median(array_1)
        Dim medHi As Double = median(array_2)
        Return (medHi - medLow) / (medHi + medLow)
    End Function

    Public Function SecondCentralMoment(ByVal input() As Double) As Double
        Return (StdDev(input)) ^ 2
    End Function

    Public Function ThirdCentralMoment(ByVal input() As Double) As Double
        Dim average As Double = mean(input)
        Dim sum As Double = 0
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + (input(i) - average) ^ 3
        Next
        Return sum / input.GetLength(0)
    End Function

    Public Function FourthCentralMoment(ByVal input() As Double) As Double
        Dim average As Double = mean(input)
        Dim sum As Double = 0
        For i As Integer = 0 To input.GetLength(0) - 1
            sum = sum + (input(i) - average) ^ 4
        Next
        Return sum / input.GetLength(0)
    End Function

    Public Function Skewness(ByVal input() As Double) As Double
        Return ThirdCentralMoment(input) / (Pow(Variance(input), 1.5))
    End Function

    Public Function kurtosis(ByVal input() As Double) As Double
        Return (FourthCentralMoment(input) / (Pow(Variance(input), 2))) - 3
    End Function



End Class